home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d1 / bnchutil.arc / QSORT.DOC < prev    next >
Text File  |  1991-04-30  |  79KB  |  1,651 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.                                           
  23.  
  24.  
  25.                                           
  26.  
  27.  
  28.                                QSORT -- Version 3.22                               QSORT -- Version 3.22
  29.                                           
  30.                              Text File Sorting Utility                             Text File Sorting Utility
  31.                                           
  32.                                           
  33.                                           
  34.                                           
  35.                                           
  36.                                           
  37.                                           
  38.                                           
  39.                                           
  40.                                           
  41.  
  42.  
  43.                        Copyright 1985, 86, 87, 88 - Ben Baker                       Copyright 1985, 86, 87, 88 - Ben Baker
  44.                                           
  45.                                 All rights reserved                                All rights reserved
  46.  
  47.  
  48.                                           
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.                                  Table of Contents                                 Table of Contents
  74.  
  75.  
  76.  
  77.        Introduction                                                1
  78.           About Shareware                                          1
  79.           Notation                                                 2
  80.  
  81.        The QSORT Command and Options                               3
  82.           The /<key_spec> Parameter                                4
  83.           The /F<len> Parameter                                    5
  84.           The /T[<tag>] Parameter                                  5
  85.           The /D[<fields>][<delim>[<term>]] Parameter              6
  86.           The /R Parameter                                         7
  87.           The /S[V] Parameter                                      7
  88.           The /? Parameter                                         9
  89.           The "2><error_file>" parameter                           9
  90.  
  91.        Lexicographic Sorting                                      11
  92.  
  93.        Examples                                                   12
  94.  
  95.        Error Messages and Return Codes                            14
  96.           Command Line Errors                                     15
  97.           Memory Errors                                           16
  98.           I/O Errors                                              17
  99.           Internal Errors                                         17
  100.           ERRORLEVEL Return Codes                                 18
  101.  
  102.        Implementation Notes                                       18
  103.           General Information                                     18
  104.           Performance and DOS Configuration                       19
  105.           Performance and Input Record Type                       21
  106.           Performance and Sort Keys                               22
  107.           Performance and File Size                               23
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.                                         i
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.                                  Introduction                                 Introduction
  143.  
  144.  
  145.        QSORT was first designed to be a replacement for, and to overcome
  146.        the limitations  of DOS  SORT, but  has been enhanced a number of
  147.        times and moved to new compilers twice.  The current version will
  148.        sort files  whose size  is limited  only by available disk space.
  149.        File name(s)  may be  given explicitly  or QSORT  will sort  from
  150.        standard input  to standard  output, and so, may be used in pipes
  151.        or with  redirection.   Multiple keys  may be  specified.  Binary
  152.        files with fixed-length records may be sorted, provided only that
  153.        keys are ASCII character strings.
  154.  
  155.        QSORT tries  to be very protective of your data.  If QSORT has an
  156.        error of  any kind,  it will  terminate with the input file still
  157.        intact, and  will return to DOS with a non-zero ERRORLEVEL.  When
  158.        QSORT successfully  completes sorting  a file, it terminates with
  159.        ERRORLEVEL set to zero.
  160.  
  161.        The command  line syntax  is a super-set of DOS SORT's syntax, so
  162.        QSORT may  be used  without other  changes in  batch files  using
  163.        SORT, but  in most  cases you  will probably  want to make use of
  164.        QSORT's greater capabilities.
  165.  
  166.  
  167.        About Shareware       About Shareware
  168.  
  169.        QSORT is  the copyrighted  property of  Ben Baker.   It  is  dis-
  170.        tributed under  a license agreement with System Enhancement Asso-
  171.        ciates, Inc.  (SEA), and  is made available under the "shareware"
  172.        concept.  Shareware products are distributed freely and publicly.
  173.        You are invited to "test drive" them without cost.  But shareware
  174.        is NOT FREE!  If you use a product, you are expected to pay a fee
  175.        for its  use.  Because overhead costs are lower, this fee is usu-
  176.        ally a  fraction of the normal commercial price the product might
  177.        carry, but it is NOT zero!
  178.  
  179.        Both the author and SEA believe in the shareware concept.  We are
  180.        both opposed  to the  "crippleware" concept used by some authors,
  181.        by which a severely limited version of the product is distributed
  182.        publicly, and  the user must register in order to receive a func-                               ____                                     
  183.        tional version.  At the same time, we feel the user should be of-
  184.        fered more  incentive than  mere guilt  to register  a  shareware
  185.        product.
  186.  
  187.        We have  therefore adopted a policy of withholding the latest ma-
  188.        jor release of the QSORT program from shareware, and marketing it
  189.        only as  a commercial  product.  As of this writing, version 3.22
  190.        of the  QSORT program  is shareware and version 4.00 (see the ac-
  191.        companying history file) is a commercial product.  When version 5
  192.        is created,  the latest  release level  of version  4 will become
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.        QSORT Text Sorting Utility                                      2
  203.  
  204.  
  205.        shareware, etc..   Hence,  the version  of QSORT  you receive  as
  206.        shareware is  fully functional  and fully documented.  It is just
  207.        not the latest version available.
  208.  
  209.        If you  find this  program useful, non-commercial users are asked
  210.        to pay a license fee of $20 for each machine on which it is used.
  211.  
  212.        The license  fee for commercial use of QSORT is $35 for the first
  213.        machine.   Liberal quantity  discounts, and  site  licensing  are
  214.        available.
  215.  
  216.        On receipt  of your registration fee, you will be sent a diskette
  217.        containing the  latest commercial  version of  the QSORT  program                  ___  ______                                           
  218.        with on-disk  documentation.   The complete  commercial packagge,
  219.        including printed documentation and technical support is $50.
  220.  
  221.        This version of QSORT may be freely copied and distributed,  pro-
  222.        vided that  1) it  is distributed  under the name "QSORT," and 2)
  223.        the documentation file always accompanies it.
  224.  
  225.        Vendors wishing to distribute QSORT as a part of commercial prod-
  226.        ucts may  contact the author's representatives at the address be-
  227.        low for terms.
  228.  
  229.        Send checks or correspondence to:
  230.  
  231.             System Enhancement Associates, Inc.
  232.             21 New Street
  233.             Wayne, NJ 07470
  234.        
  235.             Phone: (201) 473-5153
  236.  
  237.  
  238.        Notation       Notation
  239.  
  240.        In defining  the command  line and  its various  parameters,  the
  241.        following notation is used:
  242.  
  243.        [<optional>] items are enclosed in square brackets.       [<optional>]                                               __________                                        
  244.  
  245.        <variable> items  appear in lower case, underscored, and are       <variable>                                                         __________                              ___________         
  246.             surrounded by  angle brackets  (<>).  They are replaced
  247.             by actual data such as a file name.
  248.  
  249.        THIS |  THAT   Choices are  separated  by  a  vertical  bar.       THIS |  THAT                                                
  250.             Select one or the other but not both.
  251.  
  252.        [THIS |  THAT]   When the  choices are  enclosed  in  square       [THIS |  THAT]                                              
  253.             brackets, they  are optional.    You  need  not  select
  254.             either.
  255.  
  256.        REPEAT. . .  The ellipsis (. . .) means the item to its left       REPEAT. . .                                                 
  257.             may be repeated as many times as necessary.
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.        QSORT Text Sorting Utility                                      3
  269.  
  270.  
  271.        UPPER CASE  items and  all special  characters  not  defined       UPPER CASE                                                  
  272.             above represent  themselves.   They are entered exactly
  273.             as they appear.
  274.  
  275.        EXAMPLES are shown in bold upper case characters.       EXAMPLES              bold                       
  276.  
  277.  
  278.  
  279.                          The QSORT Command and Options                         The QSORT Command and Options
  280.  
  281.  
  282.        QSORT is invoked with the following command:
  283.  
  284.             QSORT [<in_file>[<out_file>]] [/<key_spec>]. . .            QSORT [<in_file>[<out_file>]] [/<key_spec>]. . .                   _________ __________     __________      
  285.                  [/F<len> | /D[<fields>][<delim>[<term>] |                 [/F<len> | /D[<fields>][<delim>[<term>] |                    _____      ________  _______ ______   
  286.                  /T[<tag>]] [/R] [/S[V]] [/?] "[2><error_file>]"                 /T[<tag>]] [/R] [/S[V]] [/?] "[2><error_file>]"                    _____                         ____________  
  287.  
  288.        Note that  all parameters  on the command line are optional.  The
  289.        <in_file> and  <out_file> parameters  are "ASCII-Z"  file  speci-       _________      __________                                        
  290.        fiers.   They may  contain disk and path information in the stan-
  291.        dard DOS format, but must not contain "wild-card" characters.  If
  292.        <in_file> is missing, QSORT sorts from standard input to standard       _________                                                        
  293.        output.   These are  files defined and opened by DOS before QSORT
  294.        is loaded.   (See  your DOS manual concerning the use of redirec-
  295.        tion and pipes.)
  296.  
  297.        If <in_file>  is given but <out_file> is missing, QSORT creates a          _________               __________                            
  298.        temporary file in the directory containing <in_file> and sorts to                                                  _________             
  299.        the temporary  file.   On  successful  completion  of  the  sort,
  300.        <in_file> is  deleted and  the temporary is renamed to <in_file>.       _________                                              _________ 
  301.        The effect is an apparent "sort-in-place."
  302.  
  303.        If both  file names  are given,  <in_file> is  unchanged and  the                                        _________                       
  304.        sorted output  is written to <out_file>.  Note that the following                                    __________                          
  305.        two commands are exactly equivalent:
  306.  
  307.             QSORT  FILE.TXT  FILE.SRT            QSORT  FILE.TXT  FILE.SRT
  308.  
  309.             QSORT <FILE.TXT >FILE.SRT            QSORT <FILE.TXT >FILE.SRT
  310.  
  311.        In the  first, QSORT opens the files.  In the second, redirection
  312.        is specified  and DOS  opens the  files.  The result is the same.
  313.        It is  an error  QSORT can't  detect if  you mix  these.  For in-
  314.        stance:
  315.  
  316.             QSORT  FILE.TXT >FILE.SRT            QSORT  FILE.TXT >FILE.SRT
  317.  
  318.        will result  in a  sort-in-place.   QSORT will  open FILE.TXT but
  319.        won't know DOS has opened FILE.SRT for it, and will ignore it.
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.        QSORT Text Sorting Utility                                      4
  335.  
  336.  
  337.        The /<key_spec> Parameter       The /<key_spec> Parameter            __________          
  338.  
  339.        Up to  30 /<key_spec> parameters may be used to specify sort keys                 /                                                                        __________                                            
  340.        and are  ordered  major  to  minor  from  left  to  right.    The
  341.        /<key_spec> argument has the form:       /                                         __________                       
  342.  
  343.             /[L][+|-][<field>.][<col>][:<length>]            /[L][+|-][<field>.][<col>][:<length>]                      _______   _____   ________ 
  344.  
  345.        Note that  all elements  of this  argument are "optional," but at
  346.        least one element must be present following the slant-bar (/).                                                                 (/) 
  347.  
  348.        The 'L',  if present, specifies "lexicographic" sequence for this           'L'                                                          
  349.        key.   Lexicographic sequence is ordered first by spelling, then,
  350.        when keys have identical spelling, by capitalization.
  351.  
  352.        The minus (-) sign reverses the sorting order for this key, while                  -                                                     
  353.        the plus (+) sign (or no sign) specifies normal sort order.                 +                                                
  354.  
  355.        There are three numbers associated with every sort key: the field
  356.        number, the  starting column  within the field, and the length of
  357.        the key  in characters.   Any,  or all  of them may be given in a
  358.        /<key_spec> parameter.   QSORT  uses punctuation to identify each       /                                                                        __________                                                      
  359.        number.   A number followed by a period (.) is a field number.  A                                                .                       
  360.        number preceded by a colon (:) is a length number.  A column num-                                   :                                    
  361.        ber has  no punctuation associated with it.  It follows the field
  362.        number, if any, and precedes the length number, if any.
  363.  
  364.        The  [<field>.]   element  is  used  only  for  "delimited-field"            [       .]                                                               _______                                                    
  365.        records, and  locates this  key within  a particular  field.  The
  366.        value of  <field> must  be less  than or  equal to  the number of                 _______                                                
  367.        fields defined  with the /D parameter (see below).  If [<field>.]                                /D                            [       .]                                                               _______  
  368.        is omitted  when sorting delimited-field records, the first field
  369.        is assumed.   For  consistency, all  records are  assumed to have
  370.        "fields."   In all cases except delimited-field records, there is
  371.        precisely one field, and it spans the entire record.
  372.  
  373.        If present,  [<col>] defines the beginning column of the key.  If                    [     ]                                                                  _____                                              
  374.        omitted, column  1 is  assumed.   In the  case of delimited-field
  375.        records, column 1 is the first character of the identified field.
  376.        In all  other cases,  column 1  is the  first  character  of  the
  377.        record.
  378.  
  379.        If present,  [:<length>] defines  the key  length in  columns (or                    [:        ]                                                               ________                                          
  380.        characters).   If [:<length>] is omitted, the rest of the record,                         [:        ]                                                               ________                                     
  381.        or field in delimited-field records, is assumed to be part of the
  382.        key.
  383.  
  384.        If no  key parameters are given, the entire record, or the entire
  385.        first field is the key.
  386.  
  387.        When sorting variable-length records, any key which begins beyond
  388.        the end  of its field in a particular record is treated as a null
  389.        (zero length)  key for that record, and will sort low relative to
  390.        all records  with non-null  values for  that key.   When  sorting
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.        QSORT Text Sorting Utility                                      5
  401.  
  402.  
  403.        fixed-length records,  all defined  keys must fall within the de-
  404.        fined record  length.  <key_spec> parameters must appear in order                              __________                                
  405.        of importance, primary key first.
  406.  
  407.  
  408.        The /F<len> Parameter       The /F<len> Parameter             _____          
  409.  
  410.        The /F<len>  parameter denotes  the record  length for  a file of           /F                                                                        _____                                                      
  411.        fixed-length records.   All records in the input file MUST be ex-
  412.        actly <len> bytes long.  The records need not (but may) be termi-             _____                                                      
  413.        nated with a CR/LF sequence.  They may contain any data, even bi-
  414.        nary data,  but the  keys must  be ASCII strings.  Strings may be
  415.        terminated with  a null (binary zero) character, or may be padded
  416.        with trailing spaces to the full length of the key.
  417.  
  418.        Note that QSORT does not attempt to support Pascal style strings.
  419.        These are strings which begin with a character whose binary value
  420.        is a  character count.  This is followed by <count> characters of                                                   _______              
  421.        ASCII data,  which in  turn is followed by random data out to the
  422.        maximum length of the string.  These strings may be used as keys,
  423.        but the  programmer must insure that either the last real charac-
  424.        ter is  a null character, or the key is padded to its full length
  425.        with spaces.   QSORT must be told that the key begins in the sec-
  426.        ond character position (the first character of real data).
  427.  
  428.  
  429.        The /T[<tag>] Parameter       The /T[<tag>] Parameter              _____           
  430.  
  431.        The /T[<tag>] parameter, if present, indicates that the "records"           /T[     ]                                                                  _____                                                     
  432.        to be sorted may be more than a single line long.
  433.  
  434.        If <tag>  is also  present, it  defines a character to be used to          _____                                                         
  435.        tag the  "end-of-record."   If <tag>  is not  present, the  first                                      _____                             
  436.        empty line  terminates the  record.   For this  purpose,  "empty"
  437.        means "no  characters." A  line containing  but a single space is
  438.        not empty!  A line may be "tagged" by placing the <tag> character       ___                                               _____          
  439.        anywhere on  the last line of a logical record.  The entire line,
  440.        including the  tag character  will appear as the last line of the
  441.        record.
  442.  
  443.        Some characters  cannot be  used to represent themselves in a DOS
  444.        command line.   For  that reason,  QSORT uses  codes to represent
  445.        them.   These codes are actually a pair of characters.  The first
  446.        is always  a back-slash (\).  The second character identifies the
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.        QSORT Text Sorting Utility                                      6
  467.  
  468.  
  469.        special character  it represents.   The  following is  a table of
  470.        characters recognized by QSORT:
  471.  
  472.                \B  - Space character               \B                   
  473.                \F  - Form feed character               \F                       
  474.                \L  - Line feed character               \L                       
  475.                \N  - Newline sequence               \N                    
  476.                \R  - Carriage return               \R                   
  477.                \T  - Tab character               \T                 
  478.                \/  - The slant bar character               \/                           
  479.                \\  - Back-slash character itself               \\                               
  480.  
  481.        Thus an invisible tab character might be used to end a multi-line
  482.        logical record.   The  other characters  in this  code list don't
  483.        make much  sense in  this context,  but will  be useful in the /D                                                                      /D
  484.        parameter (see  below).  Notice that the slant bar (/), when used                                                           /            
  485.        as a delimiter character in the /T or /D parameters, must be pre-                                       /T    /D                         
  486.        fixed by  the back-slant  to prevent it from being interpreted as
  487.        the beginning of a new parameter.
  488.  
  489.        Note that  the /F<len> and /T[<tag>] parameters are incompatible,                      /F          /T[     ]                                                     _____        _____                              
  490.        and may not both be specified.
  491.  
  492.  
  493.        The /D[<fields>][<delim>[<term>]] Parameter       The /D[<fields>][<delim>[<term>]] Parameter              ________  _______ ______            
  494.  
  495.        The /D[<fields>][<delim>[<term>]]  parameter, if  present, states           /D[        ][       [      ]]                                              ________  _______ ______                                  
  496.        that this file contains delimited-field records.  In other words,
  497.        a record is made up of distinct, variable length fields separated
  498.        from one  another by  a  particular  character,  or  "delimiter."
  499.        Records are separated, or "delimited" by the "newline sequence."
  500.  
  501.        The <fields> element defines the number of variable length fields           ________                                                     
  502.        contained in each record.  All fields must be present in each and
  503.        every record.   A "null" field will be represented by two succes-
  504.        sive delimiter characters.  There must always be exactly <fields>                                                                ________
  505.        minus 1 delimiter characters in a record.
  506.  
  507.        If a  <delim> character  is present, QSORT uses it as a field de-             _______                                                    
  508.        limiter character.   Otherwise  a comma  (,) is assumed to be the
  509.        delimiter.
  510.  
  511.        If a  <term> character is also present, QSORT uses it as a record             ______                                                     
  512.        delimiter  character.    In  fact,  it  literally  redefines  the
  513.        "newline sequence" to QSORT.  More on this in a moment.
  514.  
  515.        The same  character codes  listed under  the /T  parameter may be                                                    /T                  
  516.        used to  represent these  characters.   Note that  "\N" means the                                                          "\N"          
  517.        "newline sequence."   If <term> is not present, this is the CR-LF                                ______                                  
  518.        character pair.   If  <term> is present, it represents the <term>                             ______                               ______
  519.        character.  Thus:
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.        QSORT Text Sorting Utility                                      7
  533.  
  534.  
  535.             /D3\N\T            /D3\N\T
  536.  
  537.        says that  the newline  sequence is a tab character, and that the
  538.        three fields  within  each  record  are  also  separated  by  tab
  539.        characters.  On the other hand:
  540.  
  541.             /D3\N            /D3\N
  542.  
  543.        says that fields are separated by the newline sequence, thus each
  544.        group of  three lines  constitutes one  logical record,  and each
  545.        line is a field within that record.
  546.  
  547.        The /D  parameter is  always incompatible  with the /F parameter,           /D                                              /F           
  548.        and usually  incompatible with  the /T parameter, but there is an                                           /T                           
  549.        exception when <fields> is missing, or is equal to 1.                      ________                              
  550.  
  551.        If <fields>  equals 1  (or is missing) it says that there is only          ________                                                      
  552.        one field spanning the entire record.  But that is what QSORT as-
  553.        sumes if the whole /D parameter is missing!  So why bother?                          /D                                      
  554.  
  555.        In most  ASCII files a "line" ends with a carriage return charac-
  556.        ter (CR)  followed by a line feed character (LF).  QSORT searches
  557.        for this  character pair  when it  is looking  for a "newline se-
  558.        quence."
  559.  
  560.        But not  all files use CR-LF as a line terminator.  For instance,
  561.        files imported  from UNIX or XENIX usually terminate lines with a
  562.        naked line  feed character!  And some editors produce files whose
  563.        lines end in a naked carriage return character!  So:
  564.  
  565.             /D,\L            /D,\L
  566.  
  567.        says "for  this file,  the newline sequence is a single line feed
  568.        character."   In this  case, the  comma is a place holder.  There
  569.        really is  no "delimiter  character," but  one must be present in
  570.        the parameter in order to define the <term> character.                                            ______           
  571.  
  572.  
  573.        The /R Parameter       The /R Parameter
  574.  
  575.        The /R  parameter is included for compatibility with DOS SORT and           /R                                                           
  576.        is redundant.   It  reverses the  sense of sort direction for all
  577.        sort keys.
  578.  
  579.  
  580.        The /S[V] Parameter       The /S[V] Parameter
  581.  
  582.        The /S  parameter tells  QSORT to make a statistics report to the           /S                                                           
  583.        screen at  the end  of a  run.   The report  is  written  to  the
  584.        "standard error"  device, the console, and may not be redirected.
  585.        The following  is an  actual statistics  report  "cut"  from  the
  586.        screen after QSORT had sorted a 1.3+ megabyte file:
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.        QSORT Text Sorting Utility                                      8
  599.  
  600.  
  601.               12115 records sorted
  602.                 150 bytes in longest record
  603.          
  604.              127131 sort phase comparisons
  605.               73232 merge phase comparisons
  606.          
  607.              200363 total comparisons
  608.                16.5 comparisons per input record
  609.          
  610.                  27 temporary merge files created
  611.                   2 merge passes
  612.                 2.4 average passes over data
  613.          
  614.                2:51 elapsed time
  615.  
  616.        The first two numbers are self-explanatory.  The next two are the
  617.        number of  times two  records were compared during the sort phase
  618.        and the  merge phase  respectively, followed by the total compar-
  619.        isons.
  620.  
  621.        The next  number is  total comparisons  divided by  the number of
  622.        records in the input file.  If there is no merge phase, this num-
  623.        ber is  typically 10  to 12.   If the file is large enough to re-
  624.        quire merging,  it is 12 to 20, on average.  If it is much larger
  625.        than 20,  it usually  means that there is something unusual about
  626.        your input file.  It may already be sorted, or there may be large
  627.        blocks of  records which  compare equal.   This can happen if you
  628.        sort on, say column 50 and the input file contains a large number
  629.        of records  shorter than 50 bytes. In this case, a minor sort key
  630.        at column 1 may significantly speed sorting.
  631.  
  632.        The next  two items  are self-explanatory.   "Average passes over
  633.        data" reflects the number of times each record was read and writ-
  634.        ten.   For short  files not  requiring a  merge pass, this number
  635.        will be  1.0.  When merging is needed, the last merge pass is the
  636.        one which writes the output file and it must read and write every
  637.        record exactly  once.   Thus when  only one  merge pass  is made,
  638.        there will  be exactly  2.0 "average  passes over  data." In  the
  639.        above case  the first  merge pass  processed  about  40%  of  the
  640.        records, hence the value of 2.4.
  641.  
  642.        The above  sort was performed on a Zenith 248, an eight megahertz
  643.        AT clone  with two  hard drives (C and D).  The input file was on
  644.        C; the  temporary merge  files were  placed on  D; and the output
  645.        file was written to C:.  The sort of a 1.3 megabyte file took un-
  646.        der three  minutes.   The same  sort on  an XT  should take about
  647.        seven minutes.
  648.  
  649.        The optional  subparameter, [V]  (for verbose),  causes the QSORT                                   [V]                                  
  650.        program to  make running  progress reports  to the  screen.  Each
  651.        pass during  both the sort phase and the merge phase (if any) is-
  652.        sues a  1-line report telling the merge file(s) and the number of
  653.        records being processed during that particular pass.  This is not
  654.        terribly useful  for short  files, but  for the  big ones, it can
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.        QSORT Text Sorting Utility                                      9
  665.  
  666.  
  667.        give the  user a warm comfortable feeling that something is actu-
  668.        ally being done.
  669.  
  670.  
  671.        The /? Parameter       The /? Parameter
  672.  
  673.        The /?  parameter requests  help or  parameter evaluation.   When           /?                                                           
  674.        QSORT is  executed with  the /? parameter alone, it lists a short                                    /?                                  
  675.        description of  the QSORT parameters.  If /? is entered as one of                                                 /?                     
  676.        several parameters,  QSORT will  produce a  short report  on  the
  677.        screen describing the sort it would perform based on those param-
  678.        eters without actually doing a sort.
  679.  
  680.        For example:
  681.  
  682.             QSORT /? /L5:12 /-3:2 /22 /T /R <INFILE.TXT >OUTFILE.TXT            QSORT /? /L5:12 /-3:2 /22 /T /R <INFILE.TXT >OUTFILE.TXT
  683.  
  684.        produces the following screen report:
  685.  
  686.          With the present arguments, QSORT would sort from STDIN to
  687.          STDOUT
  688.          Records are multiple lines ending with an empty line
  689.          
  690.          Key fields in descending order of importance are:
  691.            Field  Pos   Len Type
  692.          
  693.                1    5    12 Lexical Descending
  694.                1    3     2 ASCII
  695.                1   22 65535 ASCII   Descending
  696.  
  697.        This display  lists everything  QSORT knows  about  the  proposed
  698.        sort.   It shows the file name(s), if known, or in this case, the
  699.        fact that  QSORT is  being used  as a "filter" and file names are
  700.        unknown.   It lists  file characteristics,  here showing that the
  701.        input file has records "tagged" with an empty line.  And it lists
  702.        characteristics of all defined key fields.  The third key in this
  703.        report has an unspecified length.  The value "65535" merely means
  704.        that this key extends to the end of each record.
  705.  
  706.  
  707.        The "2><error_file>" parameter       The "2><error_file>" parameter              ____________           
  708.  
  709.        The QSORT  program writes  its messages  and help  and statistics
  710.        screens to the DOS standard error device.  DOS allows the user to
  711.        redirect standard  input and  standard output,  as discussed ear-
  712.        lier, but  makes no provision for redirecting standard error.  As
  713.        far as  DOS is concerned, error messages belong on the screen and
  714.        nowhere else!
  715.  
  716.        The  "2><error_file>"   parameter  provides   the  capability  of            "2>            "                                                           ____________                                             
  717.        redirecting QSORT's  messages and  screens to  the file  named in
  718.        <error_file>.   UNIX users  should recognize  the syntax  immedi-       ____________                                                     
  719.        ately.   It is borrowed from the Bourne-Shell.  Some replacements
  720.        for DOS'  COMMAND.COM, such as Polytron's PloyShell, also support
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.        QSORT Text Sorting Utility                                     10
  731.  
  732.  
  733.        this syntax.  The  parameter should be enclosed in qupte marks as
  734.        shown to prevent later versions of DOS from trying to perform the
  735.        redirection wrong!                   wrong                    _____ 
  736.  
  737.        Two variations on this parameter are also recognized by the QSORT
  738.        program.   "2>><error_file>" tells  QSORT to open <error_file> in                  "2>>            "                                                           ____________                       ____________   
  739.        append mode  and add  the messages for this run to the end of the
  740.        contents already  in <error_file>.   2>&-  turns off  all message                                            2>&-                                                    ____________                                
  741.        output from QSORT.
  742.  
  743.        A space may be inserted in front of <error_file>, and if the file                                           ____________                 
  744.        name begins  with an  ampersand (&),  a space  must precede it to                                                      ____              
  745.        avoid confusion with the last form above and generating an error.
  746.  
  747.        To summarize:
  748.  
  749.             QSORT JUNK /S "2>MESSAGES.TXT"            QSORT JUNK /S "2>MESSAGES.TXT"
  750.  
  751.        sorts the  file JUNK  in place,  writing the statistics screen to
  752.        the file  MESSAGES.TXT.   If that  file already exists, it is re-
  753.        placed by the output of this QSORT run.
  754.  
  755.             QSORT JUNK /S "2>>MESSAGES.TXT"            QSORT JUNK /S "2>>MESSAGES.TXT"
  756.  
  757.        sorts the  file JUNK in place, appending the statistics screen to
  758.        the end of the file MESSAGES.TXT.
  759.  
  760.             QSORT JUNK /S "2>&-"            QSORT JUNK /S "2>&-"
  761.  
  762.        sorts the  file JUNK  in place.  The /S parameter is meaningless,                                            /S                          
  763.        since the  "2>&-" parameter  turns off  all message  output  from                  "2>&-"                                                                                               ___                      
  764.        QSORT!
  765.  
  766.        
  767.  
  768.        The /M<len>  supported in  earlier versions of QSORT is no longer           /M                                                                        _____                                                      
  769.        required, but  will be accepted (and ignored) by QSORT.  There is
  770.        no "hard-coded"  maximum record  length in  QSORT, but there is a
  771.        practical limit.  At some time during every sort, the two longest
  772.        records in  the input  file must be compared.  Therefore, the two
  773.        longest records  must be able to fit together in the sort buffer.
  774.        The sum  of their lengths cannot exceed about 50K -- not an alto-
  775.        gether unreasonable  limitation.   QSORT can  be shoe-horned into
  776.        tighter memory  and will  run if it can find 4K for a sort buffer
  777.        and 4K  for an  output buffer,  but the  two longest records must
  778.        still fit in the sort buffer together.
  779.  
  780.        Arguments may appear in any order on the command line except that
  781.        <in_file> must  appear before  <out_file>, and  /<key_spec> argu-                                                       /                       _________                      __________        __________      
  782.        ments must appear in descending order of importance.
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.        QSORT Text Sorting Utility                                     11
  797.  
  798.  
  799.                              Lexicographic Sorting                             Lexicographic Sorting
  800.  
  801.  
  802.        The lexicographic  sorting capability was born out of my own need
  803.        to sort  word lists  with mixed  capitalization.   ASCII sequence
  804.        produced some  bizarre results  when  words  beginning  with  'Z'
  805.        sorted before  those beginning with 'a.' Case-insensitive sorting
  806.        wasn't much  better  because  upper  and  lower  case  got  mixed
  807.        randomly.
  808.  
  809.        The following table will illustrate what I mean:
  810.  
  811.             INPUT        ASCII        CASE         LEXICO-
  812.                                       INSENSITIVE  GRAPHIC
  813.        
  814.             DeLaPort     Baker        Baker        Baker            DeLaPort     Baker        Baker        Baker
  815.             Smith        Brown        brown        Brown            Smith        Brown        brown        Brown
  816.             brown        DeAngelo     bRown        bRown            brown        DeAngelo     bRown        bRown
  817.             deLaPorte    DeLaPort     Brown        brown            deLaPorte    DeLaPort     Brown        brown
  818.             Deangelo     Deangelo     Deangelo     DeAngelo            Deangelo     Deangelo     Deangelo     DeAngelo
  819.             deAngelo     Deangelo     deangelo     Deangelo            deAngelo     Deangelo     deangelo     Deangelo
  820.             Brown        DelaPort     Deangelo     Deangelo            Brown        DelaPort     Deangelo     Deangelo
  821.             smith        DelaPorte    deAngelo     deAngelo            smith        DelaPorte    deAngelo     deAngelo
  822.             delaPorte    Harry        DeAngelo     deangelo            delaPorte    Harry        DeAngelo     deangelo
  823.             DelaPort     Smith        delaPort     DeLaPort            DelaPort     Smith        delaPort     DeLaPort
  824.             DeAngelo     bRown        DelaPort     DelaPort            DeAngelo     bRown        DelaPort     DelaPort
  825.             DelaPorte    brown        delaPort     delaPort            DelaPorte    brown        delaPort     delaPort
  826.             deangelo     deAngelo     DeLaPort     delaPort            deangelo     deAngelo     DeLaPort     delaPort
  827.             Harry        deLaPorte    DelaPorte    DelaPorte            Harry        deLaPorte    DelaPorte    DelaPorte
  828.             delaPort     deLaPorte    deLaPorte    deLaPorte            delaPort     deLaPorte    deLaPorte    deLaPorte
  829.             Baker        deangelo     delaPorte    deLaPorte            Baker        deangelo     delaPorte    deLaPorte
  830.             deLaPorte    delaPort     deLaPorte    delaPorte            deLaPorte    delaPort     deLaPorte    delaPorte
  831.             Deangelo     delaPort     Harry        Harry            Deangelo     delaPort     Harry        Harry
  832.             bRown        delaPorte    smith        Smith            bRown        delaPorte    smith        Smith
  833.             delaPort     smith        Smith        smith            delaPort     smith        Smith        smith
  834.  
  835.        The first column is a list of names in arbitrary order.  The sec-
  836.        ond is  an ASCII  sort of that list.  Third, we have one possible
  837.        case-insensitive sort  of the  list.  The fourth column is what I
  838.        really wanted.   It is sorted the way these words would be sorted
  839.        in a  dictionary (or lexicon).  The third and fourth columns both
  840.        collect words  of identical  spelling together,  but in the third
  841.        column, upper  and lower  case spelling  are in  arbitrary order,
  842.        while the fourth column places upper case spelling ahead of lower
  843.        case spelling.
  844.  
  845.        For example, the two occurrences of Smith are widely separated in                                           _____                        
  846.        column 2 because one is capitalized and the other is not.  Column
  847.        3 brings  the two  together, but  in the wrong order.  They might
  848.        have been  in the  right order,  but the  order is strictly arbi-
  849.        trary.   In column 4, Smith comes before smith, and lexicographic                             _____              _____                   
  850.        sorting will  always put  them in  this order.  Notice, also that
  851.        the two occurrences of delaPort are not together in column 3, but                              ________                                  
  852.        are brought together in column 4.
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.        QSORT Text Sorting Utility                                     12
  863.  
  864.  
  865.        Lexicographic sorting  is  achieved  by  making  case-insensitive
  866.        comparisons of  entire keys.  If the keys compare equal, an ASCII
  867.        comparison is  made to  arbitrate ties.   In  other  words,  when
  868.        "lexicographic" keys  in two records have different spelling, the
  869.        case-insensitive comparison  determines the order of the records.
  870.        When  "lexicographic"  keys  are  spelled  the  same,  the  case-
  871.        sensitive comparison determines the order of the records.
  872.  
  873.        Lexicographic keys  are defined,  as indicated  above, by placing
  874.        the  letter  'L'  immediately  following  the  slant-bar  (/)  in                    'L'                                          (/)    
  875.        <key_spec> definitions.       __________             
  876.  
  877.        Lexicographic sorting  can be  very useful  when needed,  but  be
  878.        aware that  unnecessarily specifying  lexicographic ordering  may
  879.        degrade performance of QSORT.
  880.  
  881.  
  882.  
  883.                                    Examples                                   Examples
  884.  
  885.  
  886.        Produce a  sorted directory listing and display it on the console
  887.        a screen's worth at a time:
  888.  
  889.             A>DIR | QSORT | MORE            A>DIR | QSORT | MORE
  890.  
  891.        This demonstrates the use of QSORT as a "filter" in a "pipe."
  892.  
  893.        
  894.  
  895.        Produce a directory listing sorted by creation date and time, and
  896.        display it on the console a screen's worth at a time:
  897.  
  898.             A>DIR | QSORT /30:2 /24:5 /39 /34:5 | MORE            A>DIR | QSORT /30:2 /24:5 /39 /34:5 | MORE
  899.  
  900.        The output  of the  DIR command  is piped to QSORT.  The keys de-
  901.        fined are,  from left to right (major to minor), year (2 digits),
  902.        month and  day, AM/PM flag and time.  The output of QSORT is then
  903.        piped to MORE for display.
  904.  
  905.        
  906.  
  907.        Next, replace  the unsorted FILE.TXT with the same data sorted in
  908.        reverse order.  Use columns 10 to 16 as the sort key:
  909.  
  910.             C> QSORT FILE.TXT /-10:7            C> QSORT FILE.TXT /-10:7
  911.  
  912.                  or                 or
  913.  
  914.             C> QSORT FILE.TXT /10:7 /R            C> QSORT FILE.TXT /10:7 /R
  915.  
  916.                  or                 or
  917.  
  918.             C> QSORT FILE.TXT /R /+10            C> QSORT FILE.TXT /R /+10
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.        QSORT Text Sorting Utility                                     13
  929.  
  930.  
  931.        
  932.  
  933.        Next, perform  a simple  sort on  a  file  with  up  to  240-byte
  934.        records:
  935.  
  936.             C> QSORT LARGE.REC /M240            C> QSORT LARGE.REC /M240
  937.  
  938.                  or                 or
  939.  
  940.             C> QSORT LARGE.REC            C> QSORT LARGE.REC
  941.  
  942.        Note that  the "/M240"  parameter is  no  longer needed, but will                      "     "                                           
  943.        not hurt.
  944.  
  945.        
  946.  
  947.        GLOSS.TXT is  an unsorted  glossary of terms.  The term being de-
  948.        fined by  each entry  appears first, followed by several lines of
  949.        definition.   The entries  are separated by empty lines.  Produce
  950.        GLOSS.SRT, a sorted version of the glossary:
  951.  
  952.                  with redirection                 with redirection
  953.  
  954.             C> QSORT /T  <GLOSS.TXT >GLOSS.SRT            C> QSORT /T  <GLOSS.TXT >GLOSS.SRT
  955.  
  956.                  or without redirection                 or without redirection
  957.  
  958.             C> QSORT /T   GLOSS.TXT  GLOSS.SRT            C> QSORT /T   GLOSS.TXT  GLOSS.SRT
  959.  
  960.        
  961.  
  962.        A lawyer  keeps a  running log  of  his  billable  activities  in
  963.        TIME.LOG.   The first  line of  each entry is "mm/dd/yy hh:mm ac-
  964.        count#." He  always places  a tilde  (~) in the last line of each
  965.        entry.   He wishes  to sort the log by account number, and by as-
  966.        cending date and time within each account:
  967.  
  968.             C> QSORT  /16:7 /7:2 /1:5 /10:5 /T~  TIME.LOG            C> QSORT  /16:7 /7:2 /1:5 /10:5 /T~  TIME.LOG
  969.  
  970.        
  971.  
  972.        The directory  of users  for a bulletin board system is kept in a
  973.        binary file  of fixed-length  records 180  bytes long.   The user
  974.        name is  a 26-character field beginning in the first position and
  975.        the city/state  field is  a 16-character  field beginning  in the
  976.        fortieth position.  Sort the file by city/state and name.
  977.  
  978.             C> QSORT /F180 /40:16 /1:26 USER.BBS            C> QSORT /F180 /40:16 /1:26 USER.BBS
  979.  
  980.        
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.        QSORT Text Sorting Utility                                     14
  995.  
  996.  
  997.        DB.TXT is  a delimited  field output  file from  dBASE III.  Each
  998.        record contains  7 fields, delimited by commas.  Sort the file to
  999.        the screen using field 3 as a sort key.
  1000.  
  1001.             C> QSORT /D7 /3. <DB.TXT            C> QSORT /D7 /3. <DB.TXT
  1002.  
  1003.        Here, "standard input" has been redirected to the file.  Since no
  1004.        redirection is  given for  "standard output,"   DOS assigns it to
  1005.        the console by default.  This is not a "sort-in-place!"                                        ___                   
  1006.  
  1007.        
  1008.  
  1009.        You have  received a member list from the Society of End-users of
  1010.        XENIX (SEX.LST).   Sort  the list by special interest (10 columns
  1011.        beginning at 70) and name (30 columns beginning at 1).  Note that
  1012.        the file  contains no  carriage return characters.  Since SEX.LST
  1013.        is a  very large  file, we  wish to obtain running status reports
  1014.        and a final statistics report.
  1015.  
  1016.             C> QSORT  SEX.LST /70:10 /1:30 /D,\L /SV            C> QSORT  SEX.LST /70:10 /1:30 /D,\L /SV
  1017.  
  1018.        The /D  parameter is  used to  redefine the newline sequence as a           /D                                                           
  1019.        naked line feed character.
  1020.  
  1021.        
  1022.  
  1023.        The file  LABEL.TXT contains mailing label images.  Each label is
  1024.        6 lines  (1 inch)  high.  Line six is always empty and line three
  1025.        is frequently  empty.  An extended Zip code always begins in col-
  1026.        umn 20  of line  5, and extends to the end of the line.  In order
  1027.        to take  advantage of  bulk mailing  rates, the  labels  must  be
  1028.        sorted into carrier route (CARRT) order.
  1029.  
  1030.             QSORT LABEL.TXT /5.20 /D6\N            QSORT LABEL.TXT /5.20 /D6\N
  1031.  
  1032.        We must  use a "delimited field" sort rather than a "tagged line"
  1033.        sort for  two reasons:   1)  Line six is empty, not tagged with a
  1034.        special character.   When  line three is also empty a label would
  1035.        be broken  into two  pieces and separated by the sorting process.
  1036.        2) Our  sort key is not at any known offset from the beginning of
  1037.        the label.  Its position is fixed only relative to line five.
  1038.  
  1039.  
  1040.  
  1041.                         Error Messages and Return Codes                        Error Messages and Return Codes
  1042.  
  1043.  
  1044.        The QSORT program can encounter a number of different errors dur-
  1045.        ing execution.   Each will generate a brief error message on your
  1046.        console.   This section will attempt to list the messages you may
  1047.        see, and  give you  a little more detailed information about what
  1048.        might have caused the problem.
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.        QSORT Text Sorting Utility                                     15
  1061.  
  1062.  
  1063.        Command Line Errors       Command Line Errors
  1064.  
  1065.        The most  common causes  of error messages are errors in the com-
  1066.        mand line  parameters.  Particularly when using a complicated set
  1067.        of keys,  I recommend  the use of "/?" as the last parameter.  If                                         "/?"                           
  1068.        QSORT discovers an error, it will be reported.  The QSORT program
  1069.        will also  show you exactly what it would have done, had the "/?"                                                                    "/?"
  1070.        parameter not been there, but will not perform a sort.                                          ___                
  1071.  
  1072.        You may then hit the "F3" key to recall the command, edit any bad                            "F3"                                        
  1073.        parameters using the left and right cursor keys and the "INS" and
  1074.        "DEL" keys.   When  the command parses without error, and the re-
  1075.        port looks  like the  kind of sort you wish to make, hit the "F3"                                                                    "F3"
  1076.        key once  more, then back space over the "/?" parameter, then hit                                                "/?"                    
  1077.        "Enter" and QSORT will do the rest.
  1078.  
  1079.        One or  more of  the following errors might be encountered in the
  1080.        command line:
  1081.  
  1082.             Three file names specified            Three file names specified
  1083.  
  1084.        At most,  only two  file names may be given, an input file and an
  1085.        output file.  The most likely cause of this message is forgetting
  1086.        to use  the "/" character at the beginning of a key spec or other                   "/"                                                  
  1087.        parameter.
  1088.  
  1089.             Invalid command line parameter "<parameter>"            Invalid command line parameter "<parameter>"                                            ___________ 
  1090.  
  1091.        This message  is issued if QSORT receives a parameter it does not
  1092.        understand.   It is  usually a typographic error.  You meant "/D"                                                                    "/D"
  1093.        and hit  "/E" by  mistake.    The  message  displays  the  actual                "/E"                                                    
  1094.        <parameter> it did not understand.       ___________                       
  1095.  
  1096.             /D, /F and /T parameters are incompatible            /D, /F and /T parameters are incompatible
  1097.  
  1098.        Each of the above parameters tells QSORT to use a different scan-
  1099.        ning routine  to parse  records.  Since only one such routine can
  1100.        be used, it is an error to use more than one of these parameters.
  1101.        In those  unusual situations where more than one might apply, use
  1102.        the most  efficient one.   (The  order of  the parameters in this
  1103.        message is  from most efficient to least efficient.  See the sec-
  1104.        tion on  "Performance and  Input Record  Type" for  more informa-
  1105.        tion.)
  1106.  
  1107.             Multiple /<parameter> parameters encountered            Multiple /<parameter> parameters encountered                      ___________                       
  1108.  
  1109.        This message  again applies  to the /D, /F and /T parameters.  In                                           /D  /F     /T                
  1110.        this case, the same parameter appears twice in the command line.
  1111.  
  1112.             /F<length> parameter with invalid <length>            /F<length> parameter with invalid <length>
  1113.  
  1114.        No substitution  is made for "<length>" in this message.  This is                                    "<length>"                          
  1115.        the actual  message displayed.  It means that either there was no
  1116.        length specified, or the specified length was zero.
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.        QSORT Text Sorting Utility                                     16
  1127.  
  1128.  
  1129.             Keyfield "<key_spec>" begins beyond end of record            Keyfield "<key_spec>" begins beyond end of record                      __________                             
  1130.  
  1131.             Keyfield "<key_spec>" extends beyond end of record            Keyfield "<key_spec>" extends beyond end of record                      __________                              
  1132.  
  1133.        These two messages refer to fixed-length records.  A key specifi-
  1134.        cation has  told QSORT  that data exists beyond the bounds of the
  1135.        record.   For instance,  suppose that  /F20 has  been  specified.                                              /F20                      
  1136.        Then /23  would invoke  the first  message because  the record is            /23                                                         
  1137.        only 20  characters long.   Similarly /18:5 begins before the end                                             /18:5                      
  1138.        of the  record but extends beyond it, and would invoke the second
  1139.        message.   Note that  /18 is  OK.   QSORT will assume a length of                             /18                                        
  1140.        three in this case.
  1141.  
  1142.             Invalid delimited field specification - "<key_spec>"            Invalid delimited field specification - "<key_spec>"                                                     __________ 
  1143.  
  1144.        This one is similar to the previous messages.  The "field number"
  1145.        portion of  a key specification was greater than the defined num-
  1146.        ber of fields.  For example "/D5 /6.1:3" would provoke QSORT into                                   "/D5 /6.1:3"                         
  1147.        issuing this  message.   It's hard  to find  field 6 in a 5-field
  1148.        record.
  1149.  
  1150.             Multiple STDERR redirections            Multiple STDERR redirections
  1151.  
  1152.        At most,  the standard  error output  may be  redirected once.  A
  1153.        second attempt to do so will fail with this message.
  1154.  
  1155.             Invalid STDERR redirection            Invalid STDERR redirection
  1156.  
  1157.        Two conditions  cause this  message; use of 2> or 2>> as the last                                                   2>    2>>            
  1158.        parameter, with  no file specified, or use of 2>&<x> where <x> is                                                     2>&                                                                        ___       ___   
  1159.        any text other than an unadorned hyphen.
  1160.  
  1161.             ABORT -- Error(s) in command line parameter(s)            ABORT -- Error(s) in command line parameter(s)
  1162.  
  1163.        If any  of the  above messages are issued, QSORT will continue to
  1164.        scan the command line and evaluate the parameters, but will even-
  1165.        tually issue this message too.  If there are command line errors,
  1166.        QSORT will not guess about your data.  It will stop!                  ___                                      
  1167.  
  1168.  
  1169.        Memory Errors       Memory Errors
  1170.  
  1171.             ABORT -- Buffer allocation error            ABORT -- Buffer allocation error
  1172.  
  1173.        An error  of unknown origin occurred when QSORT was trying to al-
  1174.        locate memory  for its  buffers.  The most likely cause here is a
  1175.        "memory poor"  condition caused  by a too small partition under a
  1176.        multitasker such  as DoubleDOS,  or perhaps  too many "terminate-
  1177.        and-stay-resident" programs.   As an absolute minimum, QSORT must
  1178.        be able  to obtain  eight kilobytes  of contiguous memory for its
  1179.        sort buffer.
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.        QSORT Text Sorting Utility                                     17
  1193.  
  1194.  
  1195.             ABORT -- Insufficient memory            ABORT -- Insufficient memory
  1196.  
  1197.        This one  can occur at any time during the sort.  QSORT must have
  1198.        a sort buffer large enough to hold the two largest records in the
  1199.        file.  Typically, the sort buffer is about fifty kilobytes, which
  1200.        means that  if records  are shorter  than about twenty five kilo-
  1201.        bytes, QSORT can usually handle them.  This is normally a problem
  1202.        only when using the /T parameter.                           /T           
  1203.  
  1204.  
  1205.        I/O Errors       I/O Errors
  1206.  
  1207.             ABORT -- Unable to open "<file_spec>" for input            ABORT -- Unable to open "<file_spec>" for input                                     ___________           
  1208.  
  1209.        QSORT  was   attempting  to  open  <file_spec>  for  input.    If                                          ___________                   
  1210.        <file_spec> is your input file, you probably misspelled the name.       ___________                                                      
  1211.        If <file_spec>  has the  form "number.SRT" QSORT could not find a          ___________                                                   
  1212.        merge file  it thought  it had  created.  If this happens you may
  1213.        have discovered a bug.  Please send me full particulars ASAP!
  1214.  
  1215.             ABORT -- Unable to open "<file_spec>" for output            ABORT -- Unable to open "<file_spec>" for output                                     ___________            
  1216.  
  1217.        QSORT was attempting to open <file_spec> for output, and the open                                    ___________                         
  1218.        operation failed.   The  most likely cause is that you ran out of
  1219.        disk space,  and DOS was unable to expand a subdirectory.  A root
  1220.        directory cannot  be expanded, and you may have run out of direc-
  1221.        tory space.  DOS will also complain if you attempt to open a file
  1222.        with the same full name as an existing subdirectory.
  1223.  
  1224.             ABORT -- Error reading input or merge file            ABORT -- Error reading input or merge file
  1225.  
  1226.        The section  of the  program which  issues this  message does not
  1227.        know the  file name, so cannot help you much there.  This message
  1228.        may mean  that your disk has a sector going bad.  (Well, it can't
  1229.        all be good news!)
  1230.  
  1231.             ABORT -- Error writing to merge or output file            ABORT -- Error writing to merge or output file
  1232.  
  1233.        This one  could also  mean a  bad sector,  but a  far more likely
  1234.        cause is that you just ran out of disk space.
  1235.  
  1236.  
  1237.        Internal Errors       Internal Errors
  1238.  
  1239.             ABORT -- Internal QSORT error            ABORT -- Internal QSORT error
  1240.  
  1241.        In theory,  this is  an error  which "can't happen."  If you EVER                                            _______________             
  1242.        get this  message, please  notify me  with as many details as you
  1243.        can supply.   Actually I have NEVER seen this message issued by a
  1244.        released version of QSORT.
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.        QSORT Text Sorting Utility                                     18
  1259.  
  1260.  
  1261.        ERRORLEVEL Return Codes       ERRORLEVEL Return Codes
  1262.  
  1263.        When QSORT  successfully completes a sort, it terminates with DOS
  1264.        ERRORLEVEL set to zero. (See your DOS manual for more information
  1265.        on ERRORLEVEL.)   If  it terminates for ANY other reason, it sets
  1266.        ERRORLEVEL to  a non-zero  value, which  can be tested in a batch
  1267.        file.   The following  are the  ERRORLEVEL codes  QSORT uses, and
  1268.        their meanings:
  1269.  
  1270.         Code  Meaning
  1271.        
  1272.  
  1273.            0  Successful completion
  1274.            1  Command line error and/or "/?" parameter specified                                        "/?"                    
  1275.            2  Open-for-read error
  1276.            3  Open-for-write error
  1277.            4  I/O error reading file
  1278.            5  I/O error writing file
  1279.            6  Memory error
  1280.          255  Internal error
  1281.  
  1282.  
  1283.  
  1284.                              Implementation Notes                             Implementation Notes
  1285.  
  1286.  
  1287.  
  1288.        General Information       General Information
  1289.  
  1290.        QSORT is intended as an enhanced replacement for DOS SORT.  It is
  1291.        nearly fully  upward compatible,  but provides  much more  flexi-
  1292.        bility.   Multiple sort  keys may be specified, a pseudo in-place
  1293.        sort may be performed and files and/or records of any size may be
  1294.        sorted provided only that there is sufficient disk space for work
  1295.        files and  the output  file.   QSORT uses  the "quick sort" algo-
  1296.        rithm, which cannot guarantee the order of records whose keys are
  1297.        all equal.   This  is the  one "incompatibility"  with DOS  SORT,
  1298.        which retains  the original  order of  records when  its only key
  1299.        compares equal.  This is important to SORT because it must be in-
  1300.        voked multiple  times to effect a multiple key sort.  With QSORT,
  1301.        you only sort once and there are usually enough keys available to
  1302.        insure you get the order you want the first time.
  1303.  
  1304.        QSORT uses  a sort  buffer of  about 50K  bytes and will fill the
  1305.        buffer as  full as  possible, and then sort its contents.  If the
  1306.        end of  the input  file has  been reached  and no  temporary work
  1307.        files have  been generated, the sorted contents of the buffer are
  1308.        written to the output file, completing the sort operation.
  1309.  
  1310.        If the  input file  is too  large to fit into the sort buffer, as
  1311.        much of  the input  file as  possible is  read into  the  buffer,
  1312.        sorted, then  written to  a temporary work file.  This process is
  1313.        repeated as  many times  as necessary to process the entire input
  1314.        file, each time creating a new work file for the sorted output.
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.        QSORT Text Sorting Utility                                     19
  1325.  
  1326.  
  1327.        Upon completion  of the  "sort  phase,"  QSORT  begins  a  "merge
  1328.        phase."   Each work  file is  a sorted sub-set of the input file.
  1329.        Thus, work files may be read sequentially and combined to produce
  1330.        a sorted  output.  QSORT will open as many work files as DOS per-
  1331.        mits (more  on this  later).  If all the remaining work files can
  1332.        be opened,  the sorted  result is  written to  the  output  file.
  1333.        Otherwise, a new work file is created and another merge pass will
  1334.        be required.  On each merge pass, the number of work files is re-
  1335.        duced and  eventually all remaining work files will be opened and
  1336.        the sorted  output file will be written completing the sort oper-
  1337.        ation.
  1338.  
  1339.  
  1340.        Performance and DOS Configuration       Performance and DOS Configuration
  1341.  
  1342.        QSORT is smart enough to never have just one work file remaining,
  1343.        which would  require an  unnecessary copy  operation.   In  fact,
  1344.        QSORT is  smarter than  just that  in its  handling of  the merge
  1345.        phase.   If more  than one  merge pass  is required, all the data
  1346.        merged during  the first  pass will  have to  be merged again, so
  1347.        QSORT attempts to minimize the first pass.  For example, if QSORT
  1348.        discovers it  may only  open 15 files at a time, and there are 16
  1349.        temporary files,  it will only merge two files on the first pass,
  1350.        creating a  17th file  as it  does.   Then in the second pass, it
  1351.        will merge  all 15  remaining files to the output file.  The less
  1352.        data it processes twice, the faster it performs the sort!
  1353.  
  1354.        With nothing  else to  guide it, QSORT places its temporary files
  1355.        in the  default directory.  Either of two "environment variables"
  1356.        can override this.  (See your DOS manual for information on envi-
  1357.        ronment variables and the SET command.) The DOS command:
  1358.  
  1359.             SET QSTMP=<path>        or            SET QSTMP=<path>        or                      ______          
  1360.  
  1361.             SET TMP=<path>          or            SET TMP=<path>          or                    ______            
  1362.  
  1363.             SET TEMP=<path>            SET TEMP=<path>                     ______
  1364.  
  1365.        will define  a path  for QSORT to use for its temporaries.  QSORT
  1366.        first looks  for the  environment variable QSTMP.  If it does not
  1367.        exist, QSORT  next looks  for TMP or TEMP in that order.  TMP and
  1368.        TEMP are  de facto  standards used by many programs, and are usu-
  1369.        ally defined in your AUTOEXEC.BAT batch file.  You might have TMP
  1370.        specifying a  64K RAM  disk to  speed up  your compiler.  In this
  1371.        case, an  attempt to  sort a  100K file  is  doomed  to  failure.
  1372.        Rather than  redefine TMP, you may define QSTMP to force QSORT to
  1373.        use some directory on your hard disk.  In fact:
  1374.  
  1375.             SET QSTMP=\            SET QSTMP=\
  1376.  
  1377.        tells QSORT  to always  use the  root directory  of  the  default
  1378.        drive!
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.        QSORT Text Sorting Utility                                     20
  1391.  
  1392.  
  1393.             CAUTION! The  root directory  has a  fixed size, and is            CAUTION! The  root directory  has a  fixed size, and is
  1394.             NOT expandable.  For a hard disk, it typically has room            NOT expandable.  For a hard disk, it typically has room
  1395.             for only 512 file names, less one for each subdirectory            for only 512 file names, less one for each subdirectory
  1396.             and one for the volume label (if any).  Large files may            and one for the volume label (if any).  Large files may
  1397.             fail to  sort if  the QSORT program must place too many            fail to  sort if  the QSORT program must place too many
  1398.             merge files  in a  root directory.   Subdirectories, on            merge files  in a  root directory.   Subdirectories, on
  1399.             the other  hand, are  limited only  by  available  disk            the other  hand, are  limited only  by  available  disk
  1400.             space.            space.
  1401.  
  1402.        QSORT, to work properly, needs enough space on the output disk to
  1403.        hold the  output file.   Even  if the input file is to be deleted
  1404.        and resides  in the  same directory, that is not done until after
  1405.        the output file has been successfully written.  If one merge pass
  1406.        is required,  the disk space QSORT uses for temporary merge files
  1407.        will be  about 10%  larger than  the size  of the input file.  If
  1408.        more than  one merge pass will be required, allow about twice the
  1409.        size of the input file as temporary merge file space.
  1410.  
  1411.        One of  the advantages of controlling where QSORT places its tem-
  1412.        porary files  is to  insure adequate space for them.  A second is
  1413.        speed.   If the  temporary files can be placed on a separate disk
  1414.        from the  input and  output files,  disk seeking is minimized and
  1415.        performance improved.
  1416.  
  1417.        Each time  QSORT must create a new temporary merge file, the data
  1418.        put into  it will  be processed again.  Obviously, the more files
  1419.        QSORT can  open during  the merge  phase, the fewer times it will
  1420.        have to  handle each  record and  the faster  it can  sort  large
  1421.        files.   If DOS is properly pre-conditioned, QSORT can have up to
  1422.        15 temporary  merge files  open at once, and very large files can
  1423.        be sorted  with just  one sort pass and one merge pass.  Unfortu-
  1424.        nately, that capability is not automatic.
  1425.  
  1426.        DOS has  a fixed number of file "handles" that it associates with
  1427.        open files.   The  default number is eight, but DOS opens five of
  1428.        them for  standard input,  standard output, standard error, stan-
  1429.        dard printer  and standard  auxiliary device.   That leaves three
  1430.        for merging.   A  250K input  file would  produce five  temporary
  1431.        merge files  and that  would take  three merge  passes; merge two
  1432.        into one, leaving four; merge two into one leaving three; and fi-
  1433.        nally merge  three into  the output  file.  In the process, QSORT
  1434.        must read  and write about 80% of the file twice during the merge
  1435.        phase.
  1436.  
  1437.        Worse yet,  since you need at least three handles for merging, if
  1438.        you have  resident programs that have open files, you can't merge
  1439.        at all!
  1440.  
  1441.        DOS can  be told  to set aside more space for file handles.  Each
  1442.        handle is  only 39  bytes and  it's memory  very well spent.  One
  1443.        process can  have a  maximum of  20 handles open at one time, but
  1444.        since resident  processes may be using handles, I recommend 25 to
  1445.        35.  To do this, the root directory of the disk or disks you boot                                                  ______________________
  1446.        from must  contain a file named CONFIG.SYS.  If your boot disk(s)       ____                                                             
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.        QSORT Text Sorting Utility                                     21
  1457.  
  1458.  
  1459.        already contains  a CONFIG.SYS,  edit it, or if not, create it to
  1460.        contain the following line:
  1461.  
  1462.             FILES=25        (or more)            FILES=25        (or more)
  1463.  
  1464.        While we're  at it,  let's add one more thing to CONFIG.SYS which
  1465.        will improve  the performance of QSORT and many other programs as
  1466.        well.  DOS provides, by default, two disk buffers.  These are the
  1467.        buffers it  uses to  do its  disk reads  and writes.   During the
  1468.        merge phase  QSORT may have many files open at once, reading from
  1469.        them in more or less random order.  DOS may have to read the same
  1470.        physical sector  several times  to get all its data.  But DOS can
  1471.        remember what's  in each  buffer and where it came from, and will
  1472.        not re-read  a sector  it already has in a buffer.  DOS needs 528
  1473.        bytes for each buffer.  I recommend 20 buffers to make QSORT per-
  1474.        form well  under the  most adverse conditions.  This will require
  1475.        an additional  9504 bytes  or slightly more than 9K, again memory
  1476.        well spent, so we add to CONFIG.SYS the following line:
  1477.  
  1478.             BUFFERS=20            BUFFERS=20
  1479.  
  1480.        See your DOS manual for more information on CONFIG.SYS.
  1481.  
  1482.  
  1483.        Performance and Input Record Type       Performance and Input Record Type
  1484.  
  1485.        QSORT must  read and  parse logical  records before sorting them,
  1486.        then reassemble  them before  final output.   The type of records
  1487.        contained in  the file being sorted determines how much work this
  1488.        requires, and therefore has an impact on performance.
  1489.  
  1490.        The present version of QSORT can handle four record types: simple
  1491.        ASCII, tagged  ASCII, delimited field ASCII and fixed length, de-
  1492.        termined by  the presence  or absence of a /T, /D or /F parameter                                                  /T  /D    /F          
  1493.        on the command line.
  1494.  
  1495.        Fixed length  records are very structured and require no parsing.
  1496.        Other things  equal, files  of fixed length records will sort the
  1497.        fastest.
  1498.  
  1499.        When parsing  simple ASCII  records, QSORT must find and mark the
  1500.        newline sequence,  then restore it for final output.  In general,
  1501.        this is relatively fast, but is affected by line length.  In par-
  1502.        ticular, lines  containing "over-strikes"  (naked  CR  characters
  1503.        followed by more data) can significantly slow down the parsing.
  1504.  
  1505.        Tagged ASCII  records are  parsed in  a fashion similar to simple
  1506.        ASCII records,  if a  tag character  is defined.   First  the tag
  1507.        character is  found, then  the next newline sequence is found and
  1508.        marked.   The time  required is  of course dependent on the total
  1509.        length of  the logical  record, but  is fairly  fast.   If no tag
  1510.        character is  defined, two  successive newline  sequences must be
  1511.        found.   This depends not only on total length, but the number of
  1512.        lines contained in a logical record.
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.        QSORT Text Sorting Utility                                     22
  1523.  
  1524.  
  1525.        To parse  a delimited field record with n fields, n minus one de-                                              __        __              
  1526.        limiters must be found and marked, then the newline sequence must
  1527.        be found and marked.  It is similar to tagged records with no de-
  1528.        fined tag character, but because records of this type are usually
  1529.        shorter than  tagged records, parsing delimited field records may
  1530.        be a  little faster.   It is certainly slower than parsing simple
  1531.        ASCII records.
  1532.  
  1533.  
  1534.        Performance and Sort Keys       Performance and Sort Keys
  1535.  
  1536.        The sort  keys defined  on the command line have a lot to do with
  1537.        QSORT's performance.   There  isn't much  you can  do by way of a
  1538.        strategy, when  you need a particular file sorted in a particular
  1539.        way, but you should at least be aware.
  1540.  
  1541.        Several decisions  must be  made in comparing two records.  Which
  1542.        field contains the current key?  Is the field long enough to con-
  1543.        tain the  key in  one, both  or neither  record?   Are  the  keys
  1544.        lexicographic or ASCII?  If the answers to any of these questions
  1545.        will remain  constant over  the course of a sort run, they should
  1546.        be answered once, not several thousand times!
  1547.  
  1548.        QSORT has  ten record  comparison routines  varying in  degree of
  1549.        complexity.   At the  beginning of  each sort  run it selects the
  1550.        simplest one  possible, based on the parameters given, to be used
  1551.        throughout the run.
  1552.  
  1553.        If no sort key parameters are given, the entire record is used as
  1554.        a key.   The  compare routine has no decisions it must make -- it
  1555.        simply compares  the two  strings handed it.  This is the "simple
  1556.        sort," and is the fastest possible case.
  1557.  
  1558.        A sort  key that  does not  begin at  the beginning of a variable
  1559.        length record,  may not  be contained  in a  particular record at
  1560.        all, while  a fixed  length record  is known to contain all keys.
  1561.        Other things equal, files of fixed length records will sort some-
  1562.        what faster because the compare routine does not have to test for
  1563.        "key containment."
  1564.  
  1565.        Lexicographic keys  are first  compared with a "case insensitive"
  1566.        technique.   Each character is tested to see if it is alphabetic.
  1567.        If it  is, it  is converted  to lower  case.   Then the converted
  1568.        character from each record is compared.  This is obviously slower
  1569.        than  directly   comparing  two   characters.     In  the   event
  1570.        lexicographic keys compare equal, they are compared a second time
  1571.        using a  direct compare technique!  Files with lexicographic keys
  1572.        sort slower than similar files without them.
  1573.  
  1574.        In the  case of  files with  delimited field records, the compare
  1575.        routine must  find the  correct field  for each key, determine if
  1576.        the keys  are contained  within the  fields, and  finally compare
  1577.        them.   The added  step of searching for fields slows record com-
  1578.        parison.
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.        QSORT Text Sorting Utility                                     23
  1589.  
  1590.  
  1591.        In general, the more complex the data, the more complex the sort-
  1592.        ing task and the longer it will take.  QSORT attempts to optimize
  1593.        its performance  by making as many decisions as it can about your
  1594.        data up  front, then  selecting a compare routine that makes only
  1595.        the necessary decisions on a record-by-record basis.
  1596.  
  1597.  
  1598.        Performance and File Size       Performance and File Size
  1599.  
  1600.        I received  a letter  from someone which included a graph showing
  1601.        QSORT's performance  in sorting  time vs.  file size.  He said he
  1602.        had expected  an exponential,  or at  least a  logarithmic curve.
  1603.        Instead time increased linearly with file size.  I admit, it puz-
  1604.        zled me  at the time, but Codeview, Microsoft's debugger, made it
  1605.        ease for  me to  measure the  performance of the various parts of
  1606.        the QSORT  program.  It turns out that actual sorting of data ac-
  1607.        counts for  a very  small percentage of QSORT's running time.  It
  1608.        spends most  of its  time doing  I/O.   For files  up to about 50
  1609.        kilobytes, it  will read and write each record once.  From 50K to
  1610.        about 750K  there will  be one merge pass and each record will be
  1611.        read and  written twice.   Since the amount of I/O increases lin-
  1612.        early over this range of file sizes, so will sorting time.
  1613.  
  1614.        Above about  750K a second merge pass will be needed, but in this
  1615.        size range,  only seven  to ten  percent of the data will be pro-
  1616.        cessed in  the first  merge pass,  so the sort time vs size curve
  1617.        will steepen  slightly, but  will not experience a large step (as
  1618.        it did  in versions  1 and  2).   Doubling the  file size  to 1.5
  1619.        megabytes should increase the sort time about three times.
  1620.  
  1621.        Sorting time  will be  approximately proportional  to  file  size
  1622.        times the  "average passes  over data" number from the statistics
  1623.        report.   Since this  number remains a constant "2.0" over a wide
  1624.        range of  file sizes,  sorting time  will be a linear function of
  1625.        file size in that range.
  1626.  
  1627.        
  1628.  
  1629.        I hope  you find  this program useful.  Your comments and sugges-
  1630.        tions are welcome.
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.